package com.javatip.common.utils;
import oshi.SystemInfo;
import oshi.hardware.CentralProcessor;
import oshi.hardware.HardwareAbstractionLayer;
import oshi.hardware.HWDiskStore;
import oshi.hardware.GraphicsCard;

import javax.crypto.spec.SecretKeySpec;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

public class HardwareInfo {
    private static final String AES = "AES";
    private static final String SECRET_KEY = "MySecretKeyJolly";

    public static void main(String[] args) {
        SystemInfo si = new SystemInfo();
        HardwareAbstractionLayer hal = si.getHardware();

        // CPU信息
        CentralProcessor processor = hal.getProcessor();
//        System.out.println("CPU 型号: " + processor.getProcessorIdentifier().getName());
        System.out.println("CPU 编号: " + processor.getProcessorIdentifier().getProcessorID());
//        System.out.println("processor.getProcessorIdentifier().getProcessorID()方法返回值类型: "+processor.getProcessorIdentifier().getProcessorID().getClass().getName());

        // 硬盘信息
        for (HWDiskStore disk : hal.getDiskStores()) {
//            System.out.println("硬盘型号: " + disk.getModel());
            System.out.println("硬盘序列号: " + disk.getSerial());
//            System.out.println("disk.getSerial的方法返回值类型: " + disk.getSerial().getClass().getName());
            break;  // 只取第一个硬盘
        }

        // 显卡信息
        for (GraphicsCard gc : hal.getGraphicsCards()) {
//            System.out.println("显卡名称: " + gc.getName());
            System.out.println("显卡设备ID: " + gc.getDeviceId());
//            System.out.println("显卡版本信息: " + gc.getVersionInfo());
        }
    }
    public static String getCpuId() {
        SystemInfo si = new SystemInfo();
        HardwareAbstractionLayer hal = si.getHardware();
        CentralProcessor processor = hal.getProcessor();
        return processor.getProcessorIdentifier().getProcessorID();
    }

    public static String getDiskId() {
        SystemInfo si = new SystemInfo();
        HardwareAbstractionLayer hal = si.getHardware();
        for (HWDiskStore disk : hal.getDiskStores()) {
            return disk.getSerial();
        }
        return null;
    }

    public static String getGpuId() {
        SystemInfo si = new SystemInfo();
        HardwareAbstractionLayer hal = si.getHardware();
        for (GraphicsCard gc : hal.getGraphicsCards()) {
            return gc.getDeviceId();
        }
        return null;
    }

    public static String generateApplicationCode (){
        String cpuId = getCpuId();
        String diskId = getDiskId();
        String gpuId = getGpuId();
        try {
            String combined = cpuId + diskId + gpuId;
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            byte[] hash = digest.digest(combined.getBytes());

            //System.out.println("注册号: " + Base64.getEncoder().encodeToString(hash));

            return Base64.getEncoder().encodeToString(hash);
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("SHA-256算法不可用", e);
        }
    }


    public static String generateRegistrationCode(String applicationCode) {
        try {
            SecretKeySpec secretKey = new SecretKeySpec(SECRET_KEY.getBytes(), AES);
            Cipher cipher = Cipher.getInstance(AES);
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            byte[] encrypted = cipher.doFinal(applicationCode.getBytes());
            return Base64.getEncoder().encodeToString(encrypted);
        } catch (Exception e) {
            throw new RuntimeException("AES加密错误", e);
        }
    }

    public static boolean validateRegistrationCode(String applicationCode, String registrationCode) {
        try {
            SecretKeySpec secretKey = new SecretKeySpec(SECRET_KEY.getBytes(), AES);
            Cipher cipher = Cipher.getInstance(AES);
            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            byte[] decoded = Base64.getDecoder().decode(registrationCode);
            String decrypted = new String(cipher.doFinal(decoded));
            return applicationCode.equals(decrypted);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
}
